//
// Created by suhuamo on 2025/6/22.
//

#include "Logger.h"

void LogQueue::push(const std::string &msg) {
    std::lock_guard<std::mutex> lock(mutex_);
    queue_.push(msg);
    cond_.notify_one();
}

bool LogQueue::pop(std::string &msg) {
    std::unique_lock<std::mutex> lock(mutex_);
    cond_.wait(lock, [this]() {
        return is_shutdown_ || !queue_.empty();
    });

    // 除非是关闭状态且队列中没元素了，才失败。否则在有元素的情况，就算关闭了，也要把当前这个元素处理掉
    if (is_shutdown_ && queue_.empty()) {
        return false;
    }
    msg = queue_.front();
    queue_.pop();
    return true;
}

void LogQueue::shutdown() {
    std::lock_guard<std::mutex> lock(mutex_);
    is_shutdown_ = true;
    cond_.notify_all();
}

Logger::Logger(const std::string &filename): log_file_(filename, std::ios::out | std::ios::app), exit_flag_(false) {
    if (!log_file_.is_open()) {
        throw std::runtime_error("failed to open file: " + filename);
    }
    worker_thread_ = std::thread([this]() {
        std::string msg;
        while (log_queue_.pop(msg)) {
            log_file_ << msg << std::endl;
        }
    });
}

Logger::~Logger() {
    log_queue_.shutdown();
    if (worker_thread_.joinable()) {
        worker_thread_.join();
    }
    if (log_file_.is_open()) {
        log_file_.close();
    }
}

std::string Logger::getCurrentTime() {
    auto now = std::chrono::system_clock::now();
    std::time_t time = std::chrono::system_clock::to_time_t(now);

    // 将 ctime 的结果存入 string（ctime 返回格式如："Wed Jun 22 10:00:00 2025\n"）
    std::string time_str = std::ctime(&time);

    // 移除末尾的换行符（ctime 保证以 \n 结尾）
    if (!time_str.empty() && time_str.back() == '\n') {
        time_str.pop_back();  // 直接删除最后一个字符
    }

    return time_str;
}
